package cheme.ProcessModel.ModelActions;

import java.beans.PropertyChangeEvent;

import org.eclipse.gef.commands.CompoundCommand;

import cheme.ProcessModel.IModelElement;
import cheme.ProcessModel.IPropertyAware;
import cheme.ProcessModel.ModelEnv;
import cheme.ProcessModel.ProcessModelConstants;
import cheme.ProcessModel.Annotations.Annotation;
import cheme.ProcessModel.Cmds.ChemeActionCommand;
import cheme.ProcessModel.Cmds.DeleteCmd;
import cheme.ProcessModel.Cmds.IChemeCommand;
import cheme.ProcessModel.Equations.EquationField;
import cheme.ProcessModel.Interpreter.Interpreter;
import cheme.ProcessModel.Interpreter.ModelElementData;
import cheme.ProcessModel.ProcessUnits.ITerminal;
import cheme.ProcessModel.ProcessUnits.Streams.AbstractStream;
import cheme.ProcessModel.ProcessUnits.Streams.IStream;
import cheme.ProcessModel.ProcessUnits.Streams.Tags.OverallTagComponent;
import cheme.ProcessModel.ProcessUnits.Streams.Tags.TagComponent;
import cheme.ProcessModel.ProcessUnits.Streams.Tags.TagComponentList;

public class PreupdateModelActionFactory extends AbstractModelActionFactory
{
	public CompoundCommand getActions(IChemeCommand originalCmd)
	{
		IModelElement source = (IModelElement)originalCmd.getSource();
		//CompoundCommand cmd = new CompoundCommand(); 
		
		if(originalCmd instanceof DeleteCmd)
		{
			if(source instanceof EquationField)
			{
//				cmd.add(new UnhookEquationTokenCmd(source));
			}
		}
		
		return null;
	}
	
	class UnhookEquationTokenCmd extends ChemeActionCommand
	{
		public UnhookEquationTokenCmd(Object source)
		{
			super(source);
		}
		
		@Override
		public EquationField getSource()
		{
			return (EquationField)super.getSource();
		}

		@Override
		public void execute()
		{
			Interpreter interpreter = ModelEnv.getInstanceFor(getSource()).getInterpreter();
			
			if(interpreter.modelExists(getSource().getText()))
			{
				ModelElementData data = interpreter.getModelData(getSource().getText());
				data.getModel().removePropertyChangeListener(getSource());
			}
		}

		@Override
		public void undo()
		{
//			System.out.println("ploop!");
		}
	}
	
//	static final IModelAction translateToPercentage = new IModelAction()
//	{
//		public void run(PropertyChangeEvent evt)
//		{
//			if(null == evt || !evt.getPropertyName().equals(IPropertyAware.P_TEXT))
//			{
//				return;
//			}
//			
//			PropertyChangeEvent subevent = ChemePropertyChangeEvent.getSubevenFromt(IPropertyAware.P_QUANTITY, evt);
//			if(null == subevent)
//			{
//				return;
//			}
//			
//			TagComponent component = (TagComponent)evt.getSource();
//				
//			if(component.getUnits().equals("%"))
//			{
//				try
//				{
//					String overallString = ((Tag)component.getParent().getParent()).getOverallTag().getQuantity();
//					double overallDouble = Double.parseDouble(overallString);
//						
//					double componentDouble = Double.parseDouble((String)evt.getNewValue());
//					
//					double percentage = overallDouble * componentDouble;
//					
//					component.setQuantity(Double.toString(percentage));
//				}
//				catch(Exception e)
//				{
//				}
//			}
//		}
//	};
	
	static final IModelAction initOverallTagComponentAction = new IModelAction()
	{
		String identifierBase = "M";
		int identifierCount = 1;
		
		public void run(PropertyChangeEvent evt)
		{
			if(null != evt.getSource() && evt.getSource() instanceof OverallTagComponent)
			{
				String identifier = identifierBase + Integer.toString(identifierCount++);
				((OverallTagComponent)evt.getSource()).setLabel(identifier);
			}
		}
	};
	
	static final IModelAction initTagComponentAction = new IModelAction()
	{
		String identifierBase = "M";
		int identifierCount = 1;
		
		public void run(PropertyChangeEvent evt)
		{
			if(null != evt.getNewValue() && evt.getNewValue() instanceof TagComponent)
			{
				String identifier = identifierBase + Integer.toString(identifierCount++);
				((TagComponent)evt.getNewValue()).setLabel(identifier);
			}
		}
	};
	
	static final IModelAction addOverallTagComponentAction = new IModelAction()
	{
		String identifierBase = "M";
		int identifierCount = 0;
		
		public void run(PropertyChangeEvent evt)
		{
			if(evt.getPropertyName().equals(IPropertyAware.P_CHILD) && null != evt.getNewValue() && evt.getNewValue() instanceof OverallTagComponent)
			{
				((OverallTagComponent)evt.getNewValue()).setSupressUpdateProcessing(true);
				
				String identifier = identifierBase + Integer.toString(identifierCount++);
				((OverallTagComponent)evt.getNewValue()).setLabel(identifier);
				((OverallTagComponent)evt.getNewValue()).setQuantity("?");
				((OverallTagComponent)evt.getNewValue()).setUnits("grams");
				
				((OverallTagComponent)evt.getNewValue()).setSupressUpdateProcessing(false);
			}
		}
	};
	
	static final IModelAction addTagComponentAction = new IModelAction()
	{		
		public void run(PropertyChangeEvent evt)
		{
			if(evt.getPropertyName().equals(IPropertyAware.P_CHILD) && null != evt.getNewValue() && evt.getNewValue() instanceof TagComponent)
			{
				((TagComponent)evt.getNewValue()).setSupressUpdateProcessing(true);
				((TagComponent)evt.getNewValue()).initialize(((TagComponentList)evt.getSource()).getInitPolicy());
				((TagComponent)evt.getNewValue()).setSupressUpdateProcessing(false);
			}
		}
	};
	
	static final IModelAction streamConnectionAction = new IModelAction()
	{
		Annotation disconnectedStream = new Annotation(null, ProcessModelConstants.DESC_WARNING, "This stream is not connected to any functional process unit!");
		
		public void run(PropertyChangeEvent evt)
		{
			if(evt.getPropertyName().equals(IPropertyAware.P_SOURCE_STREAM) || evt.getPropertyName().equals(IPropertyAware.P_SINK_STREAM)) 
			{
				AbstractStream stream = (AbstractStream)evt.getNewValue();
				
				if(null != stream)
				{
					if(null != stream.getSource() && stream.getSource() instanceof ITerminal && null != stream.getSink() && stream.getSink() instanceof ITerminal)
					{
						/*
						 * This may get invoked for both terminals... so ensure an annotation is added only once
						 */
						if(!stream.get(IStream.TAG_INDEX).getAnnotations().contains(disconnectedStream))
						{
							stream.get(IStream.TAG_INDEX).addAnnotation(disconnectedStream);
						}
					}
					else
					{
						stream.get(IStream.TAG_INDEX).removeAnnotation(disconnectedStream);
					}
				}
			}
		}
	};
}
